package com.match.plugin.hazelcast;

import com.hazelcast.config.CacheDeserializedValues;
import com.hazelcast.config.Config;
import com.hazelcast.config.ExecutorConfig;
import com.hazelcast.config.IcmpFailureDetectorConfig;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MetadataPolicy;
import com.hazelcast.config.NetworkConfig;
import com.hazelcast.config.PartitionGroupConfig;
import com.hazelcast.config.QueueConfig;
import com.hazelcast.config.SSLConfig;
import com.hazelcast.config.SecurityConfig;
import com.hazelcast.config.SymmetricEncryptionConfig;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.config.PartitionGroupConfig.MemberGroupType;
import com.hazelcast.jet.Jet;
import com.hazelcast.jet.JetInstance;
import com.hazelcast.jet.config.JetConfig;
import com.jfinal.plugin.IPlugin;
import cn.hutool.core.collection.CollectionUtil;

public class HazelcastPlugin implements IPlugin {

	public static HazelcastInstance hazelcastInstance;
//	public static JetInstance jetInstance = null;
	public static Config config = new Config();
	public static JetConfig jConfig = new JetConfig();
	
	/**
	 * Hazelcast的主要配置在实例生成后无法动态修改
	 */
	public HazelcastPlugin(){
		if(hazelcastInstance == null){
		
			//----分组配置
			config.setClusterName("match");//每个Hazelcast实例只能参加一个组,并且不与其他组交互
			
			//----网络配置
			NetworkConfig network = config.getNetworkConfig();
			network.setPort(5701);//端口
			network.setPortAutoIncrement(Boolean.FALSE);//是否端口自动增量
			network.setPortCount(100);//端口数量
	//		network.setOutboundPorts(CollectionUtil.newArrayList());//连接到其他节点时允许的端口范围
	//		network.getInterfaces().setEnabled(Boolean.TRUE).addInterface( "192.168.1.3" );//接口配置,指定Hazelcast应该使用哪些网络接口(默认false)
			network.setSSLConfig(//ssl配置
				new SSLConfig().setEnabled(Boolean.FALSE)
			);
			network.setSymmetricEncryptionConfig(//配置对称加密
				new SymmetricEncryptionConfig()
				.setEnabled(Boolean.FALSE)//关闭对称加密(因为关闭了,下方配置不生效.只是为了暂时默认)
				.setAlgorithm("PBEWithMD5AndDES")//加密算法
				.setSalt("thesalt")//生成密钥时要使用的salt值
				.setPassword("thepass")//密码
				.setIterationCount(19)//生成密钥时要使用的迭代计数
			);
			
			//Ping故障检测器(它在OSI协议的第3层上运行，并提供对硬件和其他较低级别事件的更快，更确定的检测。该检测器可能配置为在其他检测器之一怀疑某个成员后执行额外检查，或者它可以并行工作，这是默认设置。这样，可以更快地检测到硬件和网络级别的问题。)
			network.setIcmpFailureDetectorConfig(
				new IcmpFailureDetectorConfig()
				.setEnabled(Boolean.FALSE)//关闭故障检测器(因为关闭了,下方配置不生效.只是为了暂时默认)
				.setTimeoutMilliseconds(1000)//如果没有回复，则直到尝试执行ping操作为止的毫秒数。它的默认值是1000毫秒。
				.setFailFastOnStartup(Boolean.TRUE)//指定启用ICMP后，如果集群成员无法执行ICMP ping命令，则集群成员是否无法启动。失败通常是由于操作系统级别的限制。
				.setMaxAttempts(3)//在检测器怀疑成员/节点之前，最多可尝试ping一次。默认值为2
				.setParallelMode(Boolean.TRUE)//指定是否启用并行ping检测器；与其他探测器分开工作。默认值为true。
				.setTtl(0)//数据包应经过的最大跳数。默认值为0。
			);
												  
			//(发现成员方式)这里使用通过TCP发现成员,因为其他的发现方式底层都是通过tcp/ip的
			JoinConfig join = network.getJoin();
			join.getMulticastConfig().setEnabled(Boolean.FALSE);//是否启用多播发现
			join.getAwsConfig().setEnabled(Boolean.FALSE);//是否启用EC2发现
			join.getTcpIpConfig().setEnabled(Boolean.TRUE);//是否启用TCP / IP发现
			join.getTcpIpConfig().setMembers(CollectionUtil.newArrayList("127.0.0.1:5701", "127.0.0.1:5702", "127.0.0.1:5703"));
			join.getTcpIpConfig().setConnectionTimeoutSeconds(5);
			network.setJoin(join);
			
			//设置network配置
			config.setNetworkConfig(network);
			
			
			//----分区组配置(Hazelcast使用一致的哈希算法将关键对象分布到分区中。为每个分区创建多个副本，这些分区副本分布在Hazelcast成员之间。条目存储在成员中，这些成员拥有该条目的键所分配给的分区的副本。默认情况下，总分区数为271；您可以使用configuration属性对其进行更改)
			config.setPartitionGroupConfig(
				new PartitionGroupConfig()
				.setEnabled(Boolean.FALSE)//关闭分区组配置(因为关闭了,下方配置不生效.只是为了暂时默认)
				.setGroupType(MemberGroupType.HOST_AWARE)//分区分组类型(HOST_AWARE可以使用成员的IP地址自动对成员进行分组，以便将共享同一网络接口的成员分组在一起。同一主机（IP地址或域名）上的所有成员都形成一个分区组。这有助于避免物理服务器崩溃时数据丢失，因为同一分区的多个副本未存储在同一主机上。但是，如果每个物理机有多个网络接口或域名，则此假设无效。CUSTOM类型可以看官网)
			);
			
			
			//----配置执行器服务(默认)
			config.addExecutorConfig(
				new ExecutorConfig()
				.setName("ExecutorConfig1")//取名
				.setPoolSize(16)//执行者的每个成员的执行者线程数。默认情况下，Executor配置为在池中具有16个线程。您可以使用此元素更改它
				.setQueueCapacity(0)//0表示Integer.MAX_值。
				.setStatisticsEnabled(Boolean.TRUE)//指定是否为您的执行器服务启用统计信息收集。如果设置为  false，则不能使用实现收集统计信息（使用getLocalExecutorStats()），Hazelcast Management Center也不会显示统计信息。默认值为  true。
				.setSplitBrainProtectionName("splitbrainprotectionname")//此执行程序服务使用的split-brain保护配置的名称		
			);
			
			//----安全性配置(默认),具体看官网
			SecurityConfig security = config.getSecurityConfig();
			security.setClientBlockUnmappedActions(Boolean.TRUE);
			config.setSecurityConfig(security);
			
			
			//----队列配置(默认),具体看官网
			config.addQueueConfig(
				new QueueConfig()
				.setName("MapConfig1")//取名
				.setMaxSize(0)//介于0和integer.MAX_值之间的任何整数。0表示Integer.MAX_值。默认值为0。
				.setBackupCount(1)//备份数量
			);
			
			//----map配置(默认),项目中都是用到的map,具体看官网
			config.addMapConfig(
	            new MapConfig()
	        	.setName("MapConfig1")
	        	.setInMemoryFormat(InMemoryFormat.BINARY)//二进制（默认）：键和值将存储为二进制数据
	        	.setTimeToLiveSeconds(0)//设置生存时间秒
	        	.setBackupCount(1)//备份数量
	        	.setMetadataPolicy(MetadataPolicy.CREATE_ON_UPDATE)//元数据策略:在创建和更新它们时预处理
	        	.setCacheDeserializedValues(CacheDeserializedValues.INDEX_ONLY)
			);
			
			
			//----实例名称
			config.setInstanceName("hazelcast-instance");//实例名称
			
			
			//----其他配置看jar包默认配置文件,添加进来
			
			
//			hazelcastInstance = Hazelcast.newHazelcastInstance(config);
			jConfig.setHazelcastConfig(config);
			JetInstance jetInstance = Jet.newJetInstance(jConfig);
			hazelcastInstance = jetInstance.getHazelcastInstance();
			
	//		Jet.shutdownAll();
			
		}
		
		
	}
	
	
	
	@Override
	public boolean start() {
		System.err.println("HazelcastPlugin初始化成功JetInstance");
		return true;
	}

	@Override
	public boolean stop() {
		System.err.println("HazelcastPlugin初始化失败JetInstance");
		return true;
	}
	
}
